package org.sam.swing.table.propertytable;

import java.awt.Color;
import java.beans.PropertyEditor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;

import javax.swing.SpinnerNumberModel;

import org.apache.commons.lang3.StringUtils;

import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
import com.l2fprod.common.propertysheet.DefaultProperty;
import com.l2fprod.common.propertysheet.Property;

/**
 * 生成propertyTable(属性表格) propertybean助手
 * 
 * @author sam
 *
 */
public class PropertyBeanUtil {

	/**
	 * 生成属性定义
	 * 
	 * @param field
	 *            字段
	 * @param display
	 *            显示
	 * @param category
	 *            分组
	 * @param value
	 *            字符串格式的值
	 * @throws Exception
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Property getProperty(Field field, String display, String category, String value) throws Exception {

		DefaultProperty property = new DefaultProperty();
		Class<?> cls = field.getDeclaringClass();

		// 这里根据类型需要设置初始值了
		if (Boolean.class.equals(cls)) {
			property.setValue("true".equals(value));
		} else if (Character.class.equals(cls)) {
			property.setValue(value);
		} else if (Byte.class.equals(cls)) {
			property.setValue(Byte.valueOf(value));
		} else if (Short.class.equals(cls)) {
			property.setValue(Short.valueOf(value));
		} else if (Integer.class.equals(cls)) {
			property.setValue(Integer.valueOf(value));
		} else if (Long.class.equals(cls)) {
			property.setValue(Long.valueOf(value));
		} else if (Float.class.equals(cls)) {
			property.setValue(Float.valueOf(value));
		} else if (Double.class.equals(cls)) {
			property.setValue(Double.valueOf(value));
		} else if (String.class.equals(cls)) {
			property.setValue(value);
		} else if (BigDecimal.class.equals(cls)) {
			property.setValue(new BigDecimal(value));
		} else if (BigInteger.class.equals(cls)) {
			property.setValue(new BigInteger(value));
		} else if (Date.class.equals(cls)) {
			property.setValue(Date.parse(value));
		} else if (java.sql.Date.class.equals(cls)) {
			property.setValue(java.sql.Date.valueOf(value));
		} else if (LocalDate.class.equals(cls)) {
			property.setValue(LocalDate.parse(value));
		} else if (LocalTime.class.equals(cls)) {
			property.setValue(LocalTime.parse(value));
		} else if (LocalDateTime.class.equals(cls)) {
			property.setValue(LocalDateTime.parse(value));
		} else if (Color.class.equals(cls)) {
			property.setValue(new Color(Integer.valueOf(value)));
		} else if (String[].class.equals(cls)) {
			property.setValue(value);
		} else {
			throw new RuntimeException(field.getName() + " : 未支持的类型");
		}

		property.setCategory(category);
		property.setDisplayName(display);
		property.setName(field.getName());
		property.setType(cls);

		return property;
	}

	/**
	 * 获取
	 * 
	 * @param cls
	 * @param display
	 * @param category
	 * @param name
	 * @param value
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	public static Property getProperty(Class<?> cls, String display, String category, String name, String value)
			throws Exception {
		DefaultProperty property = new DefaultProperty();

		// 这里根据类型需要设置初始值了
		if (Boolean.class.equals(cls)) {
			property.setValue("true".equals(value));
		} else if (Character.class.equals(cls)) {
			property.setValue(value);
		} else if (Byte.class.equals(cls)) {
			property.setValue(Byte.valueOf(value));
		} else if (Short.class.equals(cls)) {
			property.setValue(Short.valueOf(value));
		} else if (Integer.class.equals(cls)) {
			property.setValue(Integer.valueOf(value));
		} else if (Long.class.equals(cls)) {
			property.setValue(Long.valueOf(value));
		} else if (Float.class.equals(cls)) {
			property.setValue(Float.valueOf(value));
		} else if (Double.class.equals(cls)) {
			property.setValue(Double.valueOf(value));
		} else if (String.class.equals(cls)) {
			property.setValue(value);
		} else if (BigDecimal.class.equals(cls)) {
			property.setValue(new BigDecimal(value));
		} else if (BigInteger.class.equals(cls)) {
			property.setValue(new BigInteger(value));
		} else if (Date.class.equals(cls)) {
			property.setValue(Date.parse(value));
		} else if (java.sql.Date.class.equals(cls)) {
			property.setValue(java.sql.Date.valueOf(value));
		} else if (LocalDate.class.equals(cls)) {
			property.setValue(LocalDate.parse(value));
		} else if (LocalTime.class.equals(cls)) {
			property.setValue(LocalTime.parse(value));
		} else if (LocalDateTime.class.equals(cls)) {
			property.setValue(LocalDateTime.parse(value));
		} else if (Color.class.equals(cls)) {
			property.setValue(new Color(Integer.valueOf(value)));
		} else if (String[].class.equals(cls)) {
			property.setValue(value);
		} else {
			throw new RuntimeException(name + " : 未支持的类型");
		}

		property.setCategory(category);
		property.setDisplayName(display);
		property.setName(name);
		property.setType(cls);

		return property;
	}

	/**
	 * 生成属性定义
	 * 
	 * @param entity
	 *            对应实体
	 * @param field
	 *            字段
	 * @param display
	 *            显示值
	 * @param category
	 *            分组
	 * @param value
	 *            绑定值
	 * @return
	 * @throws Exception
	 */
	public static Property getProperty(Class<?> cls, String display, String category, String name, Object value)
			throws Exception {
		DefaultProperty property = new DefaultProperty();
		// 这里根据类型需要设置初始值了
		property.setCategory(category);
		property.setDisplayName(display);
		property.setName(name);
		property.setType(cls);
		property.setValue(value);

		return property;
	}

	/**
	 * 生成属性定义
	 * 
	 * @param entity
	 *            对应实体
	 * @param field
	 *            字段
	 * @param display
	 *            显示值
	 * @param category
	 *            分组
	 * @return
	 * @throws Exception
	 */
	public static Property getProperty(Object entity, Field field, String display, String category) throws Exception {
		DefaultProperty property = new DefaultProperty();
		// 这里根据类型需要设置初始值了
		property.setCategory(category);
		property.setDisplayName(display);
		property.setName(field.getName());
		property.setType(field.getDeclaringClass());
		property.setValue(field.get(entity));

		return property;
	}

	/**
	 * 几个特殊类型，数组等，生成自己特殊的editor
	 * 
	 * @param cls
	 *            值类型
	 * @param value
	 *            值列表
	 * @return 特殊生成editor，有默认类型则返回null
	 * @throws Exception
	 */
	public static PropertyEditor getPropertyEditor(Class<?> cls, String value) throws Exception {
		return getPropertyEditor(cls, value, false);
	}

	/**
	 * 几个特殊类型，数组等，生成自己特殊的editor
	 * 
	 * @param cls
	 *            类型
	 * @param value
	 *            => value,min,max,step的方式 值
	 * @param range
	 *            是否是范围，不是就是枚举
	 * @return
	 * @throws Exception
	 */
	public static PropertyEditor getPropertyEditor(Class<?> cls, String value, boolean range) throws Exception {
		if (cls == null)
			return null;

		PropertyEditor editor = null;

		if (range) {
			if (Double.class.equals(cls)) {
				String[] split = value.split(",");
				double[] modelValues = new double[] { 0.0, 0.0, 1.0, 0.1 };
				if (split != null && split.length == 4) {
					try {
						modelValues[0] = Double.valueOf(split[0]);
						modelValues[1] = Double.valueOf(split[1]);
						modelValues[2] = Double.valueOf(split[2]);
						modelValues[3] = Double.valueOf(split[3]);
					} catch (Exception ex) {
						// 忽略错误
					}
				}

				editor = new SpnnierPropertyEditor(cls,
						new SpinnerNumberModel(modelValues[0], modelValues[1], modelValues[2], modelValues[3]));
				
			} else if (Integer.class.equals(cls)){
				String[] split = value.split(",");
				int[] modelValues = new int[] { 0, 0, 100, 1 };
				if (split != null && split.length == 4) {
					try {
						modelValues[0] = Integer.valueOf(split[0]);
						modelValues[1] = Integer.valueOf(split[1]);
						modelValues[2] = Integer.valueOf(split[2]);
						modelValues[3] = Integer.valueOf(split[3]);
					} catch (Exception ex) {
						// 忽略错误
					}
				}

				editor = new SpnnierPropertyEditor(cls,
						new SpinnerNumberModel(modelValues[0], modelValues[1], modelValues[2], modelValues[3]));
			}
		} else {
			if (String[].class.equals(cls) || int[].class.equals(cls) || Integer[].class.equals(cls)) {
				editor = new ComboBoxPropertyEditor();
				if (!StringUtils.isEmpty(value)) {
					((ComboBoxPropertyEditor) editor).setAvailableValues(value.split(","));
				}
			} else {
				return null;
			}
		}

		return editor;
	}
}
